/* **********************************************************************************
 *
 * Copyright (c) TMF.AscendedThemeKit.Unthemed.NET Project. All rights reserved.
 *
 * This source code is subject to terms and conditions of the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed. A copy of the license can be found in the License.html file
 * at the root of this distribution. If you can not locate the Shared Source License
 * for TMF.AscendedThemeKit.Unthemed, please send an email to ascend_adm@hotmail.com.
 * By using this source code in any fashion, you are agreeing to be bound by
 * the terms of the Shared Source License for TMF.AscendedThemeKit.Unthemed.NET.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * **********************************************************************************/

using TMF.AscendedThemeKit.Unthemed.Resources;
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Collections;

namespace TMF.AscendedThemeKit.Unthemed.Windows.Forms
{
    /// <summary>
    ///  Renders a gradient tab page based on properties.
    /// </summary>
    public class GradientTabPageRender : IDisposable
    {
        private bool _enabled = true;
        private Color _backColor;
        private int _buttonHeight;
        
        private GradientTabPage _parentGradientTabPage;
        private GradientNavigationButtonRender _gradientNavigationButtonRender;
        private bool _disposed;
        private bool _useCompatibleTextRendering;        
        private Color _tabGradientHighColor;
        private Color _tabGradientLowColor;
        private RenderMode _renderMode;
        private bool _rightToLeft;

        /// <summary>
        /// Occurs when the BackColor property changes. 
        /// </summary>
        public event EventHandler BackColorChanged;

        /// <summary>
        /// Occurs when the Enabled property changes.
        /// </summary>
        internal event EventHandler EnabledChanged;

        /// <summary>
        /// Initializes a new instance of the GradientTabPageRender class.
        /// </summary>
        /// <param name="parentControl">The parent gradient tab control.</param>
        public GradientTabPageRender(GradientTabPage parentControl)
        {
            if (parentControl == null)
            {
                throw new ArgumentNullException("parentControl");

            }

            this._parentGradientTabPage = parentControl;
            this._renderMode = RenderMode.Gradient;
            this._gradientNavigationButtonRender = new GradientNavigationButtonRender();
            this._gradientNavigationButtonRender.GradientHighColor = SystemColors.ButtonHighlight;
            this._gradientNavigationButtonRender.GradientLowColor = SystemColors.GradientActiveCaption;
            this._gradientNavigationButtonRender.ForeColor = SystemColors.ControlText;
            this._gradientNavigationButtonRender.TextAlign = ContentAlignment.MiddleLeft;
            this._gradientNavigationButtonRender.RenderMode = this._renderMode;

            Font navigationButtonFont = new Font(this._parentGradientTabPage.Font, FontStyle.Bold);
            try
            {
                this._gradientNavigationButtonRender.Font = (Font)navigationButtonFont.Clone();
            }
            catch
            {
                throw;
            }
            finally
            {
                navigationButtonFont.Dispose();
            }

            this._tabGradientHighColor = SystemColors.ButtonHighlight;
            this._tabGradientLowColor = SystemColors.GradientActiveCaption;
            this._gradientNavigationButtonRender.Border = new Border(0, 1, 0, 0);
            this._gradientNavigationButtonRender.Padding = new Padding(4, 0, 4, 0);
            this._buttonHeight = 32;          
        }
        

        /// <summary>
        /// Gets or sets a value indicating whether the control can respond to user interaction.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Boolean . true if the control can respond to user interaction; otherwise, false. The default is true. 
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public bool Enabled
        {
            get
            {
                return this._enabled;
            }

            set
            {
                if (value == this._enabled)
                {
                    return;
                }

                this._enabled = value;
                this.CreateColors();
            }
        }
        
        /// <summary>
        /// Specifies the back color for the control.
        /// </summary>
        /// <value>
        /// 	<para>
        /// System.Drawing.Color . Specifies the color to use on the background.
        /// </para>
        /// 	<para>
        /// This property is read/write. 
        /// </para>
        /// </value>
        public Color BackColor
        {
            get
            {
                return this._backColor;
            }
            set
            {
                if (value == this._backColor)
                {
                    return;
                }

                this._backColor = value;
                this.OnBackColorChanged(new EventArgs());
            }
        }

        

        /// <summary>
        /// Specifies the painting style applied to the background in a control.
        /// </summary>
        public RenderMode RenderMode
        {
            get
            {
                return this._renderMode;
            }
            set
            {
                if (value == this._renderMode)
                {
                    return;
                }
                this._renderMode = value;
                this.ResetRenderMode();
            }

        }


        /// <summary>
        /// Gets or sets the button active gradient high color.
        /// </summary>
        public Color TabActiveGradientHighColor
        {
            get
            {
                return this._gradientNavigationButtonRender.ActiveGradientHighColor;
            }

            set
            {
                if (value == this._gradientNavigationButtonRender.ActiveGradientHighColor)
                {
                    return;
                }

                this._gradientNavigationButtonRender.ActiveGradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the tab active gradient low color.
        /// </summary>
        public Color TabActiveGradientLowColor
        {
            get
            {
                return this._gradientNavigationButtonRender.ActiveGradientLowColor;
            }

            set
            {
                if (value == this._gradientNavigationButtonRender.ActiveGradientLowColor)
                {
                    return;

                }
                this._gradientNavigationButtonRender.ActiveGradientLowColor = value;
            }
        }


        /// <summary>
        /// Gets or sets the tab forecolor.
        /// </summary>
        public Color TabForeColor
        {
            get
            {
                return this._gradientNavigationButtonRender.ForeColor;
            }
            set
            {
                this._gradientNavigationButtonRender.ForeColor = value;
            }
        }

        /// <summary>
        /// Gets or sets the tab font.
        /// </summary>
        public Font TabFont
        {
            get
            {
                return this._gradientNavigationButtonRender.Font;
            }
            set
            {
                this._gradientNavigationButtonRender.Font = value;
            }

        }

        /// <summary>
        /// Gets or sets the tab gradient high color.
        /// </summary>
        public Color TabGradientHighColor
        {
            get
            {
                return this._tabGradientHighColor;

            }

            set
            {
                if (value == this._tabGradientHighColor)
                {
                    return;

                }

                this._tabGradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the tab gradient low color.
        /// </summary>
        public Color TabGradientLowColor
        {
            get
            {
                return this._tabGradientLowColor;  
          
            }

            set
            {
                if (value == this._tabGradientLowColor)
                {
                    return;

                }

                this._tabGradientLowColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the buttun height
        /// </summary>
        public int ButtonHeight
        {
            get
            {
                return this._buttonHeight;
            }
            set
            {
                if (value == this._buttonHeight)
                {
                    return;
                }
                this._buttonHeight = value;
            }

        }

        /// <summary>
        /// Gets or sets the gradient high (lighter) color for the tab when it is moused over.
        /// </summary>
        public Color TabHighlightGradientHighColor
        {
            get
            {
                return this._gradientNavigationButtonRender.HighlightGradientHighColor;

            }

            set
            {
                if (value == this._gradientNavigationButtonRender.HighlightGradientHighColor)
                {
                    return;

                }

                this._gradientNavigationButtonRender.HighlightGradientHighColor = value;

            }

        }

        /// <summary>
        /// Gets or sets the gradient high (lighter) color for the tab when it is moused over.
        /// </summary>
        public Color TabHighlightGradientLowColor
        {
            get
            {
                return this._gradientNavigationButtonRender.HighlightGradientLowColor;

            }

            set
            {
                if (value == this._gradientNavigationButtonRender.HighlightGradientLowColor)
                {
                    return;

                }

                this._gradientNavigationButtonRender.HighlightGradientLowColor = value;

            }

        }

        
        /// <summary>
        /// Gets or sets if the control should render text right to left.
        /// </summary>
        public bool RightToLeft
        {
            get
            {
                return this._rightToLeft;

            }

            set
            {
                if (this._rightToLeft == value)
                {
                    return;

                }

                this._rightToLeft = value;
                this._gradientNavigationButtonRender.RightToLeft = value;

            }

        }
                

        /// <summary>
        /// Gets or sets a value that determines whether to use the compatible text rendering engine (GDI+) or not (GDI). 
        /// </summary>
        /// <value>
        /// true if the compatible text rendering engine (GDI+) is used; otherwise, false. 
        /// </value>
        public bool UseCompatibleTextRendering
        {
            get
            {
                return this._useCompatibleTextRendering;

            }

            set
            {
                this._useCompatibleTextRendering = value;
                this._gradientNavigationButtonRender.UseCompatibleTextRendering = value;

            }

        }

        #region IDisposable Members

        /// <summary>
        /// Releases all resources used.
        /// </summary>
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
            return;

        }

        /// <summary>
        /// Releases all resources used.
        /// </summary>
        /// <param name="disposing">true or false</param>
        protected virtual void Dispose(bool disposing)
        {
            if (!this._disposed)
            {
                if (disposing)
                {
                    if (this._gradientNavigationButtonRender != null) this._gradientNavigationButtonRender.Dispose();

                }

            }

            this._disposed = true;

        }

        /// <summary>
        /// Creates the colors used to draw the control.
        /// </summary>
        /// <remarks>
        /// Takes the alpha and enabled into account.
        /// </remarks>
        protected void CreateColors()
        {
            //To do 
            // For future
        }


        /// <param name="e">An System.EventArgs that contains the event data.</param>
        protected virtual void OnEnabledChanged(System.EventArgs e)
        {
            this.CreateColors();

            if (this.EnabledChanged != null)
            {
                this.EnabledChanged(this, e);

            }

        }

        /// <summary>
        /// Renders the gradient background.
        /// </summary>
        /// <param name="e">Provides data for the Paint event.</param>
        public virtual void Render(PaintEventArgs e)
        {
            SetRenderingHints(e);
            this.CreateColors();
            
        }

        /// <summary>
        /// Sets the rendering hints based on the AntiAlias property.
        /// </summary>
        /// <param name="e">A System.Windows.Forms.PaintEventArgs that contains the event data.</param>
        /// <remarks>
        /// This methid must be called before any drawing methods are called.
        /// </remarks>
        private static void SetRenderingHints(System.Windows.Forms.PaintEventArgs e)
        {
            e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
            e.Graphics.SmoothingMode = SmoothingMode.Default;    
      
        }

        #endregion

        /// <summary>
        /// Fires the event indicating that the control backColor has changed.  Inheriting controls should use this in favour of actually listening to the event, but should not forget to call base.OnBackColorChanged() to ensure that the event is still fired for external listeners.
        /// </summary>
        /// <param name="e">A System.EventArgs that contains the event data.</param>
        public void OnBackColorChanged(EventArgs e)
        {
            if (this.BackColorChanged != null)
            {
                this.BackColorChanged(this, e);
            }
        }
      
        /// <summary>
        /// Resets the colors associated with the control.
        /// </summary>
        public virtual void ResetColors()
        {
            this.CreateColors();
            this._gradientNavigationButtonRender.ResetColors();

        }

        private void ResetRenderMode()
        {
            this._gradientNavigationButtonRender.RenderMode = this._renderMode;
        }

    }

}
